package com.hk.commons;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class IdcardUtils {
	 /** 中国公民身份证号码最小长度。 */
    public static final int CHINA_ID_MIN_LENGTH = 15;
 
    /** 中国公民身份证号码最大长度。 */
    public static final int CHINA_ID_MAX_LENGTH = 18;
 
    /** 省、直辖市代码表 */
    public static final String cityCode[] = {
            "11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41",
            "42", "43", "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71",
            "81", "82", "91"
    };
 
    /** 每位加权因子 */
    public static final int power[] = {
            7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
    };
 
    /** 第18位校检码 */
    public static final String verifyCode[] = {
            "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"
    };
    /** 最低年限 */
    public static final int MIN = 1930;
    public static Map<String, String> provCodes = new HashMap<String, String>();
    
    public static Map<String, String> cityCodes = new HashMap<String, String>();
    
    /** 台湾身份首字母对应数字 */
    public static Map<String, Integer> twFirstCode = new HashMap<String, Integer>();
    /** 香港身份首字母对应数字 */
    public static Map<String, Integer> hkFirstCode = new HashMap<String, Integer>();
    
    static {
        provCodes.put("11", "北京");
        provCodes.put("12", "天津");
        provCodes.put("13", "河北");
        provCodes.put("14", "山西");
        provCodes.put("15", "内蒙古");
        provCodes.put("21", "辽宁");
        provCodes.put("22", "吉林");
        provCodes.put("23", "黑龙江");
        provCodes.put("31", "上海");
        provCodes.put("32", "江苏");
        provCodes.put("33", "浙江");
        provCodes.put("34", "安徽");
        provCodes.put("35", "福建");
        provCodes.put("36", "江西");
        provCodes.put("37", "山东");
        provCodes.put("41", "河南");
        provCodes.put("42", "湖北");
        provCodes.put("43", "湖南");
        provCodes.put("44", "广东");
        provCodes.put("45", "广西");
        provCodes.put("46", "海南");
        provCodes.put("50", "重庆");
        provCodes.put("51", "四川");
        provCodes.put("52", "贵州");
        provCodes.put("53", "云南");
        provCodes.put("54", "西藏");
        provCodes.put("61", "陕西");
        provCodes.put("62", "甘肃");
        provCodes.put("63", "青海");
        provCodes.put("64", "宁夏");
        provCodes.put("65", "新疆");
        provCodes.put("71", "台湾");
        provCodes.put("81", "香港");
        provCodes.put("82", "澳门");
        provCodes.put("91", "国外");
        
        cityCodes.put("1101", "北京市市辖区");
        cityCodes.put("1102", "北京市市辖县");
        cityCodes.put("1201", "天津市市辖区");
        cityCodes.put("1202", "天津市市辖县");
        cityCodes.put("1301", "河北省石家庄市");
        cityCodes.put("1302", "河北省唐山市");
        cityCodes.put("1303", "河北省秦皇岛市");
        cityCodes.put("1304", "河北省邯郸市");
        cityCodes.put("1305", "河北省邢台市");
        cityCodes.put("1306", "河北省保定市");
        cityCodes.put("1307", "河北省张家口市");
        cityCodes.put("1308", "河北省承德市");
        cityCodes.put("1309", "河北省沧洲市");
        cityCodes.put("1310", "河北省廊坊市");
        cityCodes.put("1311", "河北省衡水市");
        cityCodes.put("1321", "河北省邯郸地区");
        cityCodes.put("1322", "河北省邢台地区");
        cityCodes.put("1323", "河北省石家庄市");
        cityCodes.put("1324", "河北省保定地区");
        cityCodes.put("1325", "河北省张家口地区");
        cityCodes.put("1326", "河北省承德地区");
        cityCodes.put("1328", "河北省河北省廊坊地区");
        cityCodes.put("1329", "河北省沧州地区");
        cityCodes.put("1330", "河北省衡水地区");
        cityCodes.put("1401", "山西省太原市");
        cityCodes.put("1402", "山西省大同市");
        cityCodes.put("1403", "山西省阳泉市");
        cityCodes.put("1404", "山西省长治市");
        cityCodes.put("1405", "山西省晋城市");
        cityCodes.put("1406", "山西省朔州市");
        cityCodes.put("1407", "山西省晋中市");
        cityCodes.put("1408", "山西省运城市");
        cityCodes.put("1409", "山西省忻州市");
        cityCodes.put("1410", "山西省临汾市");
        cityCodes.put("1411", "山西省吕梁市");
        cityCodes.put("1421", "山西省雁北地区");
        cityCodes.put("1422", "山西省忻洲地区");
        cityCodes.put("1423", "山西省吕梁地区");
        cityCodes.put("1424", "山西省晋中地区");
        cityCodes.put("1426", "山西省临汾地区");
        cityCodes.put("1427", "山西省运城地区");
        cityCodes.put("1501", "内蒙古呼和浩特市");
        cityCodes.put("1502", "内蒙古包头市");
        cityCodes.put("1503", "内蒙古乌海市");
        cityCodes.put("1504", "内蒙古赤峰市");
        cityCodes.put("1505", "内蒙古通辽市");
        cityCodes.put("1506", "内蒙古鄂尔多斯市");
        cityCodes.put("1507", "内蒙古呼伦贝尔市");
        cityCodes.put("1508", "内蒙古巴彦淖尔市");
        cityCodes.put("1509", "内蒙古乌兰察布市");
        cityCodes.put("1521", "内蒙古呼伦贝尔盟");
        cityCodes.put("1522", "内蒙古兴安盟");
        cityCodes.put("1523", "内蒙古哲里木盟");
        cityCodes.put("1525", "内蒙古锡林郭勒盟");
        cityCodes.put("1526", "内蒙古乌兰察布盟");
        cityCodes.put("1527", "内蒙古伊克昭盟");
        cityCodes.put("1528", "内蒙古巴彦淖尔盟");
        cityCodes.put("1529", "内蒙古阿拉善盟");
        cityCodes.put("2101", "辽宁省沈阳市");
        cityCodes.put("2102", "辽宁省大连市");
        cityCodes.put("2103", "辽宁省鞍山市");
        cityCodes.put("2104", "辽宁省抚顺市");
        cityCodes.put("2105", "辽宁省本溪市");
        cityCodes.put("2106", "辽宁省丹东市");
        cityCodes.put("2107", "辽宁省锦州市");
        cityCodes.put("2108", "辽宁省营口市");
        cityCodes.put("2109", "辽宁省阜新市");
        cityCodes.put("2110", "辽宁省辽阳市");
        cityCodes.put("2111", "辽宁省盘锦市");
        cityCodes.put("2112", "辽宁省铁岭市");
        cityCodes.put("2113", "辽宁省朝阳市");
        cityCodes.put("2114", "辽宁省葫芦岛市(锦西市)");
        cityCodes.put("2121", "辽宁省铁岭市");
        cityCodes.put("2122", "辽宁省朝阳市");
        cityCodes.put("2201", "吉林省长春市");
        cityCodes.put("2202", "吉林省吉林市");
        cityCodes.put("2203", "吉林省四平市");
        cityCodes.put("2204", "吉林省辽源市");
        cityCodes.put("2205", "吉林省通化市");
        cityCodes.put("2206", "吉林省白山市(浑江市)");
        cityCodes.put("2207", "吉林省松原市");
        cityCodes.put("2208", "吉林省白城市");
        cityCodes.put("2223", "吉林省白城地区");
        cityCodes.put("2224", "吉林省延边朝鲜族自治州");
        cityCodes.put("2301", "黑龙江哈尔滨市");
        cityCodes.put("2302", "黑龙江齐齐哈尔市");
        cityCodes.put("2303", "黑龙江鸡西市");
        cityCodes.put("2304", "黑龙江鹤岗市");
        cityCodes.put("2305", "黑龙江双鸭山市");
        cityCodes.put("2306", "黑龙江大庆市");
        cityCodes.put("2307", "黑龙江伊春市");
        cityCodes.put("2308", "黑龙江佳木斯市");
        cityCodes.put("2309", "黑龙江七台河市");
        cityCodes.put("2310", "黑龙江牡丹江市");
        cityCodes.put("2311", "黑龙江黑河市");
        cityCodes.put("2312", "黑龙江绥化市");
        cityCodes.put("2321", "黑龙江松花江地区");
        cityCodes.put("2323", "黑龙江绥化地区");
        cityCodes.put("2324", "黑龙江佳木斯地区");
        cityCodes.put("2325", "黑龙江牡丹江地区");
        cityCodes.put("2326", "黑龙江黑河地区");
        cityCodes.put("2327", "黑龙江大兴安岭地区");
        cityCodes.put("3101", "上海市市辖区");
        cityCodes.put("3102", "上海市市辖县");
        cityCodes.put("3201", "江苏省南京市");
        cityCodes.put("3202", "江苏省无锡市");
        cityCodes.put("3203", "江苏省徐州市");
        cityCodes.put("3204", "江苏省常州市");
        cityCodes.put("3205", "江苏省苏州市");
        cityCodes.put("3206", "江苏省南通市");
        cityCodes.put("3207", "江苏省连云港市");
        cityCodes.put("3208", "江苏淮安(淮阴)市");
        cityCodes.put("3209", "江苏省盐城市");
        cityCodes.put("3210", "江苏省扬州市");
        cityCodes.put("3211", "江苏省镇江市");
        cityCodes.put("3212", "江苏省泰州市");
        cityCodes.put("3213", "江苏省宿迁市");
        cityCodes.put("3301", "浙江省杭州市");
        cityCodes.put("3302", "浙江省宁波市");
        cityCodes.put("3303", "浙江省温州市");
        cityCodes.put("3304", "浙江省嘉兴市");
        cityCodes.put("3305", "浙江省湖洲市");
        cityCodes.put("3306", "浙江省绍兴市");
        cityCodes.put("3307", "浙江省金华市");
        cityCodes.put("3308", "浙江省衢州市");
        cityCodes.put("3309", "浙江省舟山市");
        cityCodes.put("3310", "浙江省台州市");
        cityCodes.put("3311", "浙江省丽水市");
        cityCodes.put("3325", "浙江省丽水地区");
        cityCodes.put("3326", "浙江省台州地区");
        cityCodes.put("3327", "浙江省舟山地区");
        cityCodes.put("3401", "安徽省合肥市");
        cityCodes.put("3402", "安徽省芜湖市");
        cityCodes.put("3403", "安徽省蚌埠市");
        cityCodes.put("3404", "安徽省淮南市");
        cityCodes.put("3405", "安徽省马鞍山市");
        cityCodes.put("3406", "安徽省淮北市");
        cityCodes.put("3407", "安徽省铜陵市");
        cityCodes.put("3408", "安徽省安庆市");
        cityCodes.put("3410", "安徽省黄山市");
        cityCodes.put("3411", "安徽省滁州市");
        cityCodes.put("3412", "安徽省阜阳市");
        cityCodes.put("3413", "安徽省宿州市");
        cityCodes.put("3414", "安徽省巢湖市");
        cityCodes.put("3415", "安徽省六安市");
        cityCodes.put("3416", "安徽省亳州市");
        cityCodes.put("3417", "安徽省池州市");
        cityCodes.put("3418", "安徽省宣城市");
        cityCodes.put("3421", "安徽省阜阳地区");
        cityCodes.put("3422", "安徽省宿县地区");
        cityCodes.put("3423", "安徽省滁县地区");
        cityCodes.put("3424", "安徽省六安地区");
        cityCodes.put("3425", "安徽省宣城地区");
        cityCodes.put("3426", "安徽省巢湖地区");
        cityCodes.put("3427", "安徽省徽州地区");
        cityCodes.put("3428", "安徽省安庆地区");
        cityCodes.put("3429", "安徽省池州地区");
        cityCodes.put("3501", "福建省福州市");
        cityCodes.put("3502", "福建省厦门市");
        cityCodes.put("3503", "福建省莆田市");
        cityCodes.put("3504", "福建省三明市");
        cityCodes.put("3505", "福建省泉州市");
        cityCodes.put("3506", "福建省漳州市");
        cityCodes.put("3507", "福建省南平市");
        cityCodes.put("3508", "福建省龙岩市");
        cityCodes.put("3509", "福建省宁德市");
        cityCodes.put("3521", "福建省南平地区");
        cityCodes.put("3522", "福建省宁德地区");
        cityCodes.put("3526", "福建省龙岩地区");
        cityCodes.put("3527", "福建省三明市");
        cityCodes.put("3601", "江西省南昌市");
        cityCodes.put("3602", "江西省景德镇市");
        cityCodes.put("3603", "江西省萍乡市");
        cityCodes.put("3604", "江西省九江市");
        cityCodes.put("3605", "江西省新余市");
        cityCodes.put("3606", "江西省鹰潭市");
        cityCodes.put("3607", "江西省赣州市");
        cityCodes.put("3608", "江西省吉安市");
        cityCodes.put("3609", "江西省宜春市");
        cityCodes.put("3610", "江西省抚州市");
        cityCodes.put("3611", "江西省上饶市");
        cityCodes.put("3621", "江西省赣州地区");
        cityCodes.put("3622", "江西省宜春地区");
        cityCodes.put("3623", "江西省上饶地区");
        cityCodes.put("3624", "江西省吉安地区");
        cityCodes.put("3625", "江西省抚州地区");
        cityCodes.put("3626", "江西省九江地区");
        cityCodes.put("3701", "山东省济南市");
        cityCodes.put("3702", "山东省青岛市");
        cityCodes.put("3703", "山东省淄博市");
        cityCodes.put("3704", "山东省枣庄市");
        cityCodes.put("3705", "山东省东营市");
        cityCodes.put("3706", "山东省烟台市");
        cityCodes.put("3707", "山东省潍坊市");
        cityCodes.put("3708", "山东省济宁市");
        cityCodes.put("3709", "山东省泰安市");
        cityCodes.put("3710", "山东省威海市");
        cityCodes.put("3711", "山东省日照市");
        cityCodes.put("3712", "山东省莱芜市");
        cityCodes.put("3713", "山东省临沂市");
        cityCodes.put("3714", "山东省德州市");
        cityCodes.put("3715", "山东省聊城市");
        cityCodes.put("3716", "山东省滨州市");
        cityCodes.put("3717", "山东省菏泽市");
        cityCodes.put("3721", "山东省烟台地区");
        cityCodes.put("3722", "山东省潍坊地区");
        cityCodes.put("3723", "山东省滨州地区");
        cityCodes.put("3724", "山东省德州地区");
        cityCodes.put("3725", "山东省聊城地区");
        cityCodes.put("3726", "山东省泰安地区");
        cityCodes.put("3727", "山东省济宁地区");
        cityCodes.put("3728", "山东省临沂地区");
        cityCodes.put("3729", "山东省菏泽地区");
        cityCodes.put("4101", "河南省郑州市");
        cityCodes.put("4102", "河南省开封市");
        cityCodes.put("4103", "河南省洛阳市");
        cityCodes.put("4104", "河南省平顶山市");
        cityCodes.put("4105", "河南省安阳市");
        cityCodes.put("4106", "河南省鹤壁市");
        cityCodes.put("4107", "河南省新乡市　　　　　　");
        cityCodes.put("4108", "河南省焦作市");
        cityCodes.put("4109", "河南省濮阳市");
        cityCodes.put("4110", "河南省许昌市");
        cityCodes.put("4111", "河南省漯河市");
        cityCodes.put("4112", "河南省三门峡市");
        cityCodes.put("4113", "河南省南阳市");
        cityCodes.put("4114", "河南省商丘市");
        cityCodes.put("4115", "河南省信阳市");
        cityCodes.put("4116", "河南省周口市");
        cityCodes.put("4117", "河南省驻马店市");
        cityCodes.put("4123", "河南省商丘地区");
        cityCodes.put("4124", "河南省开封地区");
        cityCodes.put("4125", "河南省三门峡市");
        cityCodes.put("4127", "河南省周口地区");
        cityCodes.put("4128", "河南省驻马店地区");
        cityCodes.put("4129", "河南省南阳市(地区)");
        cityCodes.put("4130", "河南省信阳地区");
        cityCodes.put("4201", "湖北省武汉市");
        cityCodes.put("4202", "湖北省黄石市");
        cityCodes.put("4203", "湖北省十堰市");
        cityCodes.put("4204", "湖北省沙市市");
        cityCodes.put("4205", "湖北省宜昌市");
        cityCodes.put("4206", "湖北省襄樊市");
        cityCodes.put("4207", "湖北省鄂州市");
        cityCodes.put("4208", "湖北省荆门市");
        cityCodes.put("4209", "湖北省孝感市");
        cityCodes.put("4210", "湖北省荆州市");
        cityCodes.put("4211", "湖北省黄冈市");
        cityCodes.put("4212", "湖北省咸宁市");
        cityCodes.put("4213", "湖北省随州市");
        cityCodes.put("4221", "湖北省黄冈地区");
        cityCodes.put("4222", "湖北省孝感地区");
        cityCodes.put("4223", "湖北省咸宁地区");
        cityCodes.put("4224", "湖北省荆州地区");
        cityCodes.put("4225", "湖北省随州地区");
        cityCodes.put("4226", "湖北省郧阳地区");
        cityCodes.put("4227", "湖北省宜昌地区");
        cityCodes.put("4228", "湖北省恩施土家族苗族自治州");
        cityCodes.put("4229", "湖北省省直辖行政单位");
        cityCodes.put("4290", "湖北省省直辖行政单位");
        cityCodes.put("4301", "湖南省长沙市");
        cityCodes.put("4302", "湖南省株洲市");
        cityCodes.put("4303", "湖南省湘潭市");
        cityCodes.put("4304", "湖南省衡阳市");
        cityCodes.put("4305", "湖南省邵阳市");
        cityCodes.put("4306", "湖南省岳阳市");
        cityCodes.put("4307", "湖南省常德市");
        cityCodes.put("4308", "湖南省张家界(大庸)市");
        cityCodes.put("4309", "湖南省益阳市");
        cityCodes.put("4310", "湖南省郴州市");
        cityCodes.put("4311", "湖南省永州市");
        cityCodes.put("4312", "湖南省怀化市");
        cityCodes.put("4313", "湖南省娄底市");
        cityCodes.put("4321", "湖南省湘潭地区");
        cityCodes.put("4322", "湖南省岳阳地区");
        cityCodes.put("4323", "湖南省益阳地区");
        cityCodes.put("4324", "湖南省常德地区");
        cityCodes.put("4325", "湖南省娄底地区");
        cityCodes.put("4326", "湖南省邵阳地区");
        cityCodes.put("4327", "湖南省衡阳地区");
        cityCodes.put("4328", "湖南省郴州地区");
        cityCodes.put("4329", "湖南省零陵地区");
        cityCodes.put("4330", "湖南省怀化地区");
        cityCodes.put("4331", "湖南省湘西土家族苗族自治州");
        cityCodes.put("4401", "广东省广州市");
        cityCodes.put("4402", "广东省韶关市");
        cityCodes.put("4403", "广东省深圳市");
        cityCodes.put("4404", "广东省珠海市");
        cityCodes.put("4405", "广东省汕头市");
        cityCodes.put("4406", "广东省佛山市");
        cityCodes.put("4407", "广东省江门市");
        cityCodes.put("4408", "广东省湛江市");
        cityCodes.put("4409", "广东省茂名市");
        cityCodes.put("4412", "广东省肇庆市");
        cityCodes.put("4413", "广东省惠州市");
        cityCodes.put("4414", "广东省梅州市");
        cityCodes.put("4415", "广东省汕尾市");
        cityCodes.put("4416", "广东省河源市");
        cityCodes.put("4417", "广东省阳江市");
        cityCodes.put("4418", "广东省清远市");
        cityCodes.put("4419", "广东省东莞市");
        cityCodes.put("4420", "广东省中山市");
        cityCodes.put("4427", "广东省佛山市");
        cityCodes.put("4429", "广东省湛江市");
        cityCodes.put("4451", "广东省潮州市");
        cityCodes.put("4452", "广东省揭阳市");
        cityCodes.put("4453", "广东省云浮市");
        cityCodes.put("4501", "广西南宁市");
        cityCodes.put("4502", "广西柳州市");
        cityCodes.put("4503", "广西桂林市");
        cityCodes.put("4504", "广西梧州市");
        cityCodes.put("4505", "广西北海市　");
        cityCodes.put("4506", "广西防城港市");
        cityCodes.put("4507", "广西钦州市");
        cityCodes.put("4508", "广西贵港市");
        cityCodes.put("4509", "广西玉林市");
        cityCodes.put("4510", "广西百色市");
        cityCodes.put("4511", "广西贺州市");
        cityCodes.put("4512", "广西河池市");
        cityCodes.put("4513", "广西来宾市");
        cityCodes.put("4514", "广西崇左市");
        cityCodes.put("4521", "广西南宁地区");
        cityCodes.put("4522", "广西柳州地区");
        cityCodes.put("4523", "广西桂林地区");
        cityCodes.put("4524", "广西贺(梧)州地区");
        cityCodes.put("4525", "广西玉林地区");
        cityCodes.put("4526", "广西百色地区");
        cityCodes.put("4527", "广西河池地区");
        cityCodes.put("4528", "广西钦州地区");
        cityCodes.put("4600", "海南省三亚各市县");
        cityCodes.put("4601", "海南省海口市");
        cityCodes.put("4602", "海南省三亚市");
        cityCodes.put("5101", "四川省成都市");
        cityCodes.put("5102", "四川省重庆市");
        cityCodes.put("5103", "四川省自贡市");
        cityCodes.put("5104", "四川省攀枝花市");
        cityCodes.put("5105", "四川省泸州市");
        cityCodes.put("5106", "四川省德阳市");
        cityCodes.put("5107", "四川省绵阳市");
        cityCodes.put("5108", "四川省广元市");
        cityCodes.put("5109", "四川省遂宁市");
        cityCodes.put("5110", "四川省内江市");
        cityCodes.put("5111", "四川省乐山市");
        cityCodes.put("5112", "四川省万县市");
        cityCodes.put("5113", "四川省南充市");
        cityCodes.put("5114", "四川省眉山市");
        cityCodes.put("5115", "四川省宜宾市");
        cityCodes.put("5116", "四川省广安市");
        cityCodes.put("5117", "四川省达州市");
        cityCodes.put("5118", "四川省雅安市");
        cityCodes.put("5119", "四川省巴中市");
        cityCodes.put("5120", "四川省资阳市");
        cityCodes.put("5122", "四川省万县地区");
        cityCodes.put("5123", "四川省涪陵地区");
        cityCodes.put("5125", "四川省宜宾地区");
        cityCodes.put("5129", "四川省南充地区");
        cityCodes.put("5130", "四川省达川地区");
        cityCodes.put("5131", "四川省雅安地区");
        cityCodes.put("5132", "四川省阿坝藏族羌族自治州");
        cityCodes.put("5133", "四川省甘孜藏族自治州");
        cityCodes.put("5134", "四川省凉山彝族自治州");
        cityCodes.put("5135", "四川省黔江地区");
        cityCodes.put("5136", "四川省广安地区");
        cityCodes.put("5137", "四川省巴中地区");
        cityCodes.put("5138", "四川省眉山地区");
        cityCodes.put("5139", "四川省资阳地区");
        cityCodes.put("5201", "贵州省贵阳市");
        cityCodes.put("5202", "贵州省六盘水市");
        cityCodes.put("5203", "贵州省遵义市");
        cityCodes.put("5204", "贵州省安顺市");
        cityCodes.put("5221", "贵州省遵义地区");
        cityCodes.put("5222", "贵州省铜仁地区");
        cityCodes.put("5223", "贵州省黔西南布依族苗族自治州");
        cityCodes.put("5224", "贵州省毕节地区");
        cityCodes.put("5225", "贵州省安顺地区");
        cityCodes.put("5226", "贵州省黔东南苗族侗族自治州");
        cityCodes.put("5227", "贵州省黔南布依族苗族自治州");
        cityCodes.put("5301", "云南省昆明市");
        cityCodes.put("5302", "云南省东川市");
        cityCodes.put("5303", "云南省曲靖市");
        cityCodes.put("5304", "云南省玉溪市");
        cityCodes.put("5305", "云南省保山市");
        cityCodes.put("5306", "云南省昭通市");
        cityCodes.put("5307", "云南省丽江市");
        cityCodes.put("5308", "云南省思茅市");
        cityCodes.put("5309", "云南省临沧市");
        cityCodes.put("5321", "云南省昭通地区");
        cityCodes.put("5322", "云南省曲靖地区");
        cityCodes.put("5323", "云南省楚雄彝族自治州");
        cityCodes.put("5324", "云南省玉溪地区");
        cityCodes.put("5325", "云南省红河哈尼族彝族自治州");
        cityCodes.put("5326", "云南省文山壮族苗族自治州");
        cityCodes.put("5327", "云南省思茅地区");
        cityCodes.put("5328", "云南省西双版纳傣族自治州");
        cityCodes.put("5329", "云南省大理白族自治州");
        cityCodes.put("5330", "云南省保山地区");
        cityCodes.put("5331", "云南省德宏傣族景颇族自治州");
        cityCodes.put("5332", "云南省丽江地区");
        cityCodes.put("5333", "云南省怒江傈僳族自治州");
        cityCodes.put("5334", "云南省迪庆藏族自治州");
        cityCodes.put("5335", "云南省临沧地区");
        cityCodes.put("5401", "西藏拉萨市");
        cityCodes.put("5421", "西藏昌都地区");
        cityCodes.put("5422", "西藏山南地区");
        cityCodes.put("5423", "西藏日喀则地区");
        cityCodes.put("5424", "西藏那曲地区");
        cityCodes.put("5425", "西藏阿里地区");
        cityCodes.put("5426", "西藏林芝地区");
        cityCodes.put("5427", "西藏江孜地区");
        cityCodes.put("6101", "陕西省西安市");
        cityCodes.put("6102", "陕西省铜川市");
        cityCodes.put("6103", "陕西省宝鸡市");
        cityCodes.put("6104", "陕西省咸阳市");
        cityCodes.put("6105", "陕西省渭南市");
        cityCodes.put("6106", "陕西省延安市");
        cityCodes.put("6107", "陕西省汉中市");
        cityCodes.put("6108", "陕西省榆林市");
        cityCodes.put("6109", "陕西省安康市");
        cityCodes.put("6110", "陕西省商洛市");
        cityCodes.put("6121", "陕西省渭南地区");
        cityCodes.put("6122", "陕西省咸阳地区");
        cityCodes.put("6123", "陕西省汉中地区");
        cityCodes.put("6124", "陕西省安康地区");
        cityCodes.put("6125", "陕西省商洛地区");
        cityCodes.put("6126", "陕西省延安地区");
        cityCodes.put("6127", "陕西省榆林地区");
        cityCodes.put("6201", "甘肃省兰州市");
        cityCodes.put("6202", "甘肃省嘉峪关市");
        cityCodes.put("6203", "甘肃省金昌市");
        cityCodes.put("6204", "甘肃省白银市");
        cityCodes.put("6205", "甘肃省天水市");
        cityCodes.put("6206", "甘肃省武威市");
        cityCodes.put("6207", "甘肃省张掖市");
        cityCodes.put("6208", "甘肃省平凉市");
        cityCodes.put("6209", "甘肃省酒泉市");
        cityCodes.put("6210", "甘肃省庆阳市");
        cityCodes.put("6211", "甘肃省定西市");
        cityCodes.put("6212", "甘肃省陇南市");
        cityCodes.put("6221", "甘肃省酒泉地区");
        cityCodes.put("6222", "甘肃省张掖地区");
        cityCodes.put("6223", "甘肃省武威地区");
        cityCodes.put("6224", "甘肃省定西地区");
        cityCodes.put("6226", "甘肃省陇南地区");
        cityCodes.put("6227", "甘肃省平凉地区");
        cityCodes.put("6228", "甘肃省庆阳地区");
        cityCodes.put("6229", "甘肃省临夏回族自治州");
        cityCodes.put("6230", "甘肃省甘南藏族自治州");
        cityCodes.put("6301", "青海省西宁市");
        cityCodes.put("6321", "青海省海东地区");
        cityCodes.put("6322", "青海省海北藏族自治州");
        cityCodes.put("6323", "青海省黄南藏族自治州");
        cityCodes.put("6325", "青海省海南藏族自治州");
        cityCodes.put("6326", "青海省果洛藏族自治州");
        cityCodes.put("6327", "青海省玉树藏族自治州");
        cityCodes.put("6328", "青海省海西蒙古族藏族自治州");
        cityCodes.put("6401", "宁夏银川市");
        cityCodes.put("6402", "宁夏石嘴山市");
        cityCodes.put("6403", "宁夏吴忠市");
        cityCodes.put("6404", "宁夏固原市");
        cityCodes.put("6405", "宁夏中卫市");
        cityCodes.put("6421", "宁夏吴忠市(银南地区)");
        cityCodes.put("6422", "宁夏固原地区");
        cityCodes.put("6501", "新疆乌鲁木齐市");
        cityCodes.put("6502", "新疆克拉玛依市");
        cityCodes.put("6521", "新疆吐鲁番地区");
        cityCodes.put("6522", "新疆哈密地区");
        cityCodes.put("6523", "新疆昌吉回族自治州");
        cityCodes.put("6524", "新疆伊犁哈萨克自治州");
        cityCodes.put("6525", "新疆塔城地区");
        cityCodes.put("6526", "新疆阿勒泰地区");
        cityCodes.put("6527", "新疆博尔塔拉蒙古自治州");
        cityCodes.put("6528", "新疆巴音郭楞蒙古自治州");
        cityCodes.put("6529", "新疆阿克苏地区");
        cityCodes.put("6530", "新疆克孜勒苏柯尔克孜自治州");
        cityCodes.put("6531", "新疆喀什地区");
        cityCodes.put("6532", "新疆和田地区");
        cityCodes.put("6540", "新疆伊犁哈萨克自治州");
        cityCodes.put("6541", "新疆伊犁地区");
        cityCodes.put("6542", "新疆塔城地区");
        cityCodes.put("6543", "新疆阿勒泰地区");
        cityCodes.put("6590", "新疆省直辖行政单位");




        
        
        twFirstCode.put("A", 10);
        twFirstCode.put("B", 11);
        twFirstCode.put("C", 12);
        twFirstCode.put("D", 13);
        twFirstCode.put("E", 14);
        twFirstCode.put("F", 15);
        twFirstCode.put("G", 16);
        twFirstCode.put("H", 17);
        twFirstCode.put("J", 18);
        twFirstCode.put("K", 19);
        twFirstCode.put("L", 20);
        twFirstCode.put("M", 21);
        twFirstCode.put("N", 22);
        twFirstCode.put("P", 23);
        twFirstCode.put("Q", 24);
        twFirstCode.put("R", 25);
        twFirstCode.put("S", 26);
        twFirstCode.put("T", 27);
        twFirstCode.put("U", 28);
        twFirstCode.put("V", 29);
        twFirstCode.put("X", 30);
        twFirstCode.put("Y", 31);
        twFirstCode.put("W", 32);
        twFirstCode.put("Z", 33);
        twFirstCode.put("I", 34);
        twFirstCode.put("O", 35);
        hkFirstCode.put("A", 1);
        hkFirstCode.put("B", 2);
        hkFirstCode.put("C", 3);
        hkFirstCode.put("R", 18);
        hkFirstCode.put("U", 21);
        hkFirstCode.put("Z", 26);
        hkFirstCode.put("X", 24);
        hkFirstCode.put("W", 23);
        hkFirstCode.put("O", 15);
        hkFirstCode.put("N", 14);
    }
 
    /**
     * 将15位身份证号码转换为18位
     * 
     * @param idCard
     *            15位身份编码
     * @return 18位身份编码
     */
    public static String conver15CardTo18(String idCard) {
        String idCard18 = "";
        if (idCard.length() != CHINA_ID_MIN_LENGTH) {
            return null;
        }
        if (isNum(idCard)) {
            // 获取出生年月日
            String birthday = idCard.substring(6, 12);
            Date birthDate = null;
            try {
                birthDate = new SimpleDateFormat("yyMMdd").parse(birthday);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal = Calendar.getInstance();
            if (birthDate != null)
                cal.setTime(birthDate);
            // 获取出生年(完全表现形式,如：2010)
            String sYear = String.valueOf(cal.get(Calendar.YEAR));
            idCard18 = idCard.substring(0, 6) + sYear + idCard.substring(8);
            // 转换字符数组
            char[] cArr = idCard18.toCharArray();
            if (cArr != null) {
                int[] iCard = converCharToInt(cArr);
                int iSum17 = getPowerSum(iCard);
                // 获取校验位
                String sVal = getCheckCode18(iSum17);
                if (sVal.length() > 0) {
                    idCard18 += sVal;
                } else {
                    return null;
                }
            }
        } else {
            return null;
        }
        return idCard18;
    }
 
    /**
     * 验证身份证是否合法
     */
    public static boolean validateCard(String idCard) {
        String card = idCard.trim();
        if (validateIdCard18(card)) {
            return true;
        }
        if (validateIdCard15(card)) {
            return true;
        }
        String[] cardval = validateIdCard10(card);
        if (cardval != null) {
            if (cardval[2].equals("true")) {
                return true;
            }
        }
        return false;
    }
 
    /**
     * 验证18位身份编码是否合法
     * 
     * @param idCard 身份编码
     * @return 是否合法
     */
    public static boolean validateIdCard18(String idCard) {
        boolean bTrue = false;
        if (idCard.length() == CHINA_ID_MAX_LENGTH) {
            // 前17位
            String code17 = idCard.substring(0, 17);
            // 第18位
            String code18 = idCard.substring(17, CHINA_ID_MAX_LENGTH);
            if (isNum(code17)) {
                char[] cArr = code17.toCharArray();
                if (cArr != null) {
                    int[] iCard = converCharToInt(cArr);
                    int iSum17 = getPowerSum(iCard);
                    // 获取校验位
                    String val = getCheckCode18(iSum17);
                    if (val.length() > 0) {
                        if (val.equalsIgnoreCase(code18)) {
                            bTrue = true;
                        }
                    }
                }
            }
        }
        return bTrue;
    }
 
    /**
     * 验证15位身份编码是否合法
     * 
     * @param idCard
     *            身份编码
     * @return 是否合法
     */
    public static boolean validateIdCard15(String idCard) {
        if (idCard.length() != CHINA_ID_MIN_LENGTH) {
            return false;
        }
        if (isNum(idCard)) {
            String proCode = idCard.substring(0, 2);
            if (provCodes.get(proCode) == null) {
                return false;
            }
            String birthCode = idCard.substring(6, 12);
            Date birthDate = null;
            try {
                birthDate = new SimpleDateFormat("yy").parse(birthCode.substring(0, 2));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Calendar cal = Calendar.getInstance();
            if (birthDate != null)
                cal.setTime(birthDate);
            if (!valiDate(cal.get(Calendar.YEAR), Integer.valueOf(birthCode.substring(2, 4)),
                    Integer.valueOf(birthCode.substring(4, 6)))) {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }
 
    /**
     * 验证10位身份编码是否合法
     * 
     * @param idCard 身份编码
     * @return 身份证信息数组
     *         <p>
     *         [0] - 台湾、澳门、香港 [1] - 性别(男M,女F,未知N) [2] - 是否合法(合法true,不合法false)
     *         若不是身份证件号码则返回null
     *         </p>
     */
    public static String[] validateIdCard10(String idCard) {
        String[] info = new String[3];
        String card = idCard.replaceAll("[\\(|\\)]", "");
        if (card.length() != 8 && card.length() != 9 && idCard.length() != 10) {
            return null;
        }
        if (idCard.matches("^[a-zA-Z][0-9]{9}$")) { // 台湾
            info[0] = "台湾";
            System.out.println("11111");
            String char2 = idCard.substring(1, 2);
            if (char2.equals("1")) {
                info[1] = "M";
                System.out.println("MMMMMMM");
            } else if (char2.equals("2")) {
                info[1] = "F";
                System.out.println("FFFFFFF");
            } else {
                info[1] = "N";
                info[2] = "false";
                System.out.println("NNNN");
                return info;
            }
            info[2] = validateTWCard(idCard) ? "true" : "false";
        } else if (idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$")) { // 澳门
            info[0] = "澳门";
            info[1] = "N";
            // TODO
        } else if (idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?$")) { // 香港
            info[0] = "香港";
            info[1] = "N";
            info[2] = validateHKCard(idCard) ? "true" : "false";
        } else {
            return null;
        }
        return info;
    }
 
    /**
     * 验证台湾身份证号码
     * 
     * @param idCard
     *            身份证号码
     * @return 验证码是否符合
     */
    public static boolean validateTWCard(String idCard) {
        String start = idCard.substring(0, 1);
        String mid = idCard.substring(1, 9);
        String end = idCard.substring(9, 10);
        Integer iStart = twFirstCode.get(start);
        Integer sum = iStart / 10 + (iStart % 10) * 9;
        char[] chars = mid.toCharArray();
        Integer iflag = 8;
        for (char c : chars) {
            sum = sum + Integer.valueOf(c + "") * iflag;
            iflag--;
        }
        return (sum % 10 == 0 ? 0 : (10 - sum % 10)) == Integer.valueOf(end) ? true : false;
    }
 
    /**
     * 验证香港身份证号码(存在Bug，部份特殊身份证无法检查)
     * <p>
     * 身份证前2位为英文字符，如果只出现一个英文字符则表示第一位是空格，对应数字58 前2位英文字符A-Z分别对应数字10-35
     * 最后一位校验码为0-9的数字加上字符"A"，"A"代表10
     * </p>
     * <p>
     * 将身份证号码全部转换为数字，分别对应乘9-1相加的总和，整除11则证件号码有效
     * </p>
     * 
     * @param idCard 身份证号码
     * @return 验证码是否符合
     */
    public static boolean validateHKCard(String idCard) {
        String card = idCard.replaceAll("[\\(|\\)]", "");
        Integer sum = 0;
        if (card.length() == 9) {
            sum = (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 9
                    + (Integer.valueOf(card.substring(1, 2).toUpperCase().toCharArray()[0]) - 55) * 8;
            card = card.substring(1, 9);
        } else {
            sum = 522 + (Integer.valueOf(card.substring(0, 1).toUpperCase().toCharArray()[0]) - 55) * 8;
        }
        String mid = card.substring(1, 7);
        String end = card.substring(7, 8);
        char[] chars = mid.toCharArray();
        Integer iflag = 7;
        for (char c : chars) {
            sum = sum + Integer.valueOf(c + "") * iflag;
            iflag--;
        }
        if (end.toUpperCase().equals("A")) {
            sum = sum + 10;
        } else {
            sum = sum + Integer.valueOf(end);
        }
        return (sum % 11 == 0) ? true : false;
    }
 
    /**
     * 将字符数组转换成数字数组
     * 
     * @param ca
     *            字符数组
     * @return 数字数组
     */
    public static int[] converCharToInt(char[] ca) {
        int len = ca.length;
        int[] iArr = new int[len];
        try {
            for (int i = 0; i < len; i++) {
                iArr[i] = Integer.parseInt(String.valueOf(ca[i]));
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return iArr;
    }
 
    /**
     * 将身份证的每位和对应位的加权因子相乘之后，再得到和值
     * 
     * @param iArr
     * @return 身份证编码。
     */
    public static int getPowerSum(int[] iArr) {
        int iSum = 0;
        if (power.length == iArr.length) {
            for (int i = 0; i < iArr.length; i++) {
                for (int j = 0; j < power.length; j++) {
                    if (i == j) {
                        iSum = iSum + iArr[i] * power[j];
                    }
                }
            }
        }
        return iSum;
    }
 
    /**
     * 将power和值与11取模获得余数进行校验码判断
     * 
     * @param iSum
     * @return 校验位
     */
    public static String getCheckCode18(int iSum) {
        String sCode = "";
        switch (iSum % 11) {
        case 10:
            sCode = "2";
            break;
        case 9:
            sCode = "3";
            break;
        case 8:
            sCode = "4";
            break;
        case 7:
            sCode = "5";
            break;
        case 6:
            sCode = "6";
            break;
        case 5:
            sCode = "7";
            break;
        case 4:
            sCode = "8";
            break;
        case 3:
            sCode = "9";
            break;
        case 2:
            sCode = "x";
            break;
        case 1:
            sCode = "0";
            break;
        case 0:
            sCode = "1";
            break;
        }
        return sCode;
    }
 
    /**
     * 根据身份编号获取年龄
     * 
     * @param idCard
     *            身份编号
     * @return 年龄
     */
    public static int getAgeByIdCard(String idCard) {
        int iAge = 0;
        if (idCard.length() == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        String year = idCard.substring(6, 10);
        Calendar cal = Calendar.getInstance();
        int iCurrYear = cal.get(Calendar.YEAR);
        iAge = iCurrYear - Integer.valueOf(year);
        return iAge;
    }
 
    /**
     * 根据身份编号获取生日
     * 
     * @param idCard 身份编号
     * @return 生日(yyyyMMdd)
     */
    public static String getBirthByIdCard(String idCard) {
        Integer len = idCard.length();
        if (len < CHINA_ID_MIN_LENGTH) {
            return null;
        } else if (len == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        return idCard.substring(6, 14);
    }
 
    /**
     * 根据身份编号获取生日年
     * 
     * @param idCard 身份编号
     * @return 生日(yyyy)
     */
    public static Short getYearByIdCard(String idCard) {
        Integer len = idCard.length();
        if (len < CHINA_ID_MIN_LENGTH) {
            return null;
        } else if (len == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        return Short.valueOf(idCard.substring(6, 10));
    }
 
    /**
     * 根据身份编号获取生日月
     * 
     * @param idCard
     *            身份编号
     * @return 生日(MM)
     */
    public static Short getMonthByIdCard(String idCard) {
        Integer len = idCard.length();
        if (len < CHINA_ID_MIN_LENGTH) {
            return null;
        } else if (len == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        return Short.valueOf(idCard.substring(10, 12));
    }
 
    /**
     * 根据身份编号获取生日天
     * 
     * @param idCard
     *            身份编号
     * @return 生日(dd)
     */
    public static Short getDateByIdCard(String idCard) {
        Integer len = idCard.length();
        if (len < CHINA_ID_MIN_LENGTH) {
            return null;
        } else if (len == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        return Short.valueOf(idCard.substring(12, 14));
    }
 
    /**
     * 根据身份编号获取性别
     * 
     * @param idCard 身份编号
     * @return 性别(M-男，F-女，N-未知)
     */
    public static String getGenderByIdCard(String idCard) {
        String sGender = "N";
        if (idCard.length() == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        String sCardNum = idCard.substring(16, 17);
        if (Integer.parseInt(sCardNum) % 2 != 0) {
            sGender = "M";
        } else {
            sGender = "F";
        }
        return sGender;
    }
 
    /**
     * 根据身份编号获取户籍省份
     * 
     * @param idCard 身份编码
     * @return 省级编码。
     */
    public static String getProvinceByIdCard(String idCard) {
        int len = idCard.length();
        String sProvince = null;
        String sProvinNum = "";
        if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) {
            sProvinNum = idCard.substring(0, 2);
        }
        sProvince = provCodes.get(sProvinNum);
        return sProvince;
    }
    
    
    /**
     * 根据身份编号获取户籍地市
     * 
     * @param idCard 身份编码
     * @return 地市编码。
     */
    public static String getCityByIdCard(String idCard) {
        int len = idCard.length();
        String sCity = null;
        String sCityNum = "";
        if (len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) {
        	sCityNum = idCard.substring(0, 4);
        }
        sCity = cityCodes.get(sCityNum);
        return sCity;
    }
    
    /**
     * 数字验证
     * 
     * @param val
     * @return 提取的数字。
     */
    public static boolean isNum(String val) {
        return val == null || "".equals(val) ? false : val.matches("^[0-9]*$");
    }
 
    /**
     * 验证小于当前日期 是否有效
     * 
     * @param iYear
     *            待验证日期(年)
     * @param iMonth
     *            待验证日期(月 1-12)
     * @param iDate
     *            待验证日期(日)
     * @return 是否有效
     */
    public static boolean valiDate(int iYear, int iMonth, int iDate) {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int datePerMonth;
        if (iYear < MIN || iYear >= year) {
            return false;
        }
        if (iMonth < 1 || iMonth > 12) {
            return false;
        }
        switch (iMonth) {
        case 4:
        case 6:
        case 9:
        case 11:
            datePerMonth = 30;
            break;
        case 2:
            boolean dm = ((iYear % 4 == 0 && iYear % 100 != 0) || (iYear % 400 == 0))
                    && (iYear > MIN && iYear < year);
            datePerMonth = dm ? 29 : 28;
            break;
        default:
            datePerMonth = 31;
        }
        return (iDate >= 1) && (iDate <= datePerMonth);
    }
}
